<?php

namespace App\Models\Traits;

use App\Extend\ListWithCountStruct;

/**
 * Common trait
 * @method static \Illuminate\Database\Query\Builder where(\Closure|string|array|\Illuminate\Contracts\Database\Query\Expression  $column)
 * @method static \Illuminate\Database\Query\Builder select(array|mixed  $columns)
 * @method static \Illuminate\Database\Query\Builder insertGetId(array $values, $sequence = null)
 * @method static int delete(mixed  $id)
 */
trait Common
{

    /**
     * 获取where条件
     * @param array $data 参数数组
     * @param array $fields 要处理的字段
     * @return array
     */
    public static function getSelfWhereCommon(Array $data , $fields = []) {
        $keys = array_keys($data);
        if($fields) {
            //去掉data里面fields没指定的字段
            $keys = array_intersect($keys , $fields);
        }
        $where = [];
        foreach($keys as $key) {
            $val = $data[$key] ?? '';
            if($val === '') continue; //过滤空值
            switch ($key) {
                case 'start_date':
                    $where[] = ['create_time', '>', strtotime($val)];
                    break;
                case 'end_date':
                    $where[] = ['create_time', '<', strtotime($val)+24*60*60-1];
                    break;
                case 'title':
                    $where[] = [$key, 'like', '%'.$val.'%'];
                    break;
                case 'nickname':
                    $where[] = [$key, 'like', '%'.$val.'%'];
                    break;
                case 'user_name':
                    $where[] = [$key, 'like', '%'.$val.'%'];
                    break;
                case 'good_name':
                    $where[] = [$key, 'like', '%'.$val.'%'];
                    break;
                default:
                    $where[] = [$key, '=', $val];
            }
        }
        //print_r($where);
        return $where;
    }

    /**
     * 验证数据是否存在
     *
     * @param array $where
     * @param string $field
     * @return \Illuminate\Database\Eloquent\Model|object|static|null
     */
    public static function existCommon($where=[], $field='id') {
        return self::select($field)->where($where)->first();
    }
    
    /**
     * 获取单条数据
     *
     * @param [type] $where
     * @param string $field
     * @param array $order
     * @return \Illuminate\Database\Eloquent\Model|object|static|null
     */
    public static function getLineCommon($where,$field='*',$order=[]) {
        $query = self::where($where)->select($field);
        if($order) {
            $query = $query->orderBy(...$order);
        }
        return $query->first();
    }

    /**
     * 根据主键获取一条数据
     *
     * @param [type] $pk
     * @param string $field
     * @return mixed|static
     */
    public static function getLineByPkCommon($pk, $field='*') {
        return self::select($field)->find($pk);
    }
    
    /**
     * 获取单个值(单条)
     *
     * @param mixed $where
     * @param string $field
     * @return mixed
     */
    public static function getValueCommon($where,$field) {
        return self::where($where)->value($field);
    }

    /**
     * 获取全部数据
     *
     * @param array $where
     * @param string $field
     * @param array $order
     * @return \Illuminate\Support\Collection
     */
    public static function getAllCommon($where=[], $field='*', $order=[]) {
        $query = self::select($field)->where($where);
        if($order) {
            $query = $query->orderBy(...$order);
        }
        return $query->get();
    }

    /**
     * 获取指定列的列表,数组形式,全部返回
     *
     * @param array $where
     * @param string $field
     * @param array $order
     * @return \Illuminate\Support\Collection
     */
    public static function getColumnAllCommon($where = [] , $field='*' , $order=[]) {
        $query = self::where($where)->orderBy(...$order);

        if(is_array($field)) {
            return $query->pluck($field[0], $field[1]);
        } else {
            return $query->pluck($field);
        }
    }
    
    /**
     * 用于分页的 `offset`
     *
     * @param integer $page
     * @param integer $limit
     * @return int
     */
    public static function getOffsetByPage($page=1, $limit=10) {
        $offset = ($page - 1) * $limit;
        return $offset;
    }

    /**
     * 获取列表带分页
     *
     * @param array $where
     * @param string $field
     * @param integer $page
     * @param integer $limit
     * @param array $order
     * @return ListWithCountStruct|bool
     */
    public static function getListWithCountCommon($where=[] , $field='*' , $page=1 , $limit=10 , $order=[]) {
        $total = self::getCountCommon($where);
        if($total === false) return false;
        if($total == 0) return self::listWithCountCommon([], 0);

        $list  = self::getListCommon($where , $field , $page , $limit , $order);
        if($list === false) return false;

        return self::listWithCountCommon($list , $total);
    }

    /**
     * 获取列表
     *
     * @param array $where
     * @param string $field
     * @param integer $page
     * @param integer $limit
     * @param array $order
     * @return \Illuminate\Support\Collection
     */
    public static function getListCommon($where = [] , $field='*' , $page=1 , $limit=10 , $order=[]) {
        $query = self::where($where)
        ->offset(self::getOffsetByPage($page, $limit))
        ->limit($limit)->select($field);
        
        if($order) {
            $query = $query->orderBy(...$order);
        }
        
        return $query->get();
    }
    
    /**
     * 获取列表.指定列.数组形式返回,支持分页
     *
     * @param array $where
     * @param string $field
     * @param integer $page
     * @param integer $limit
     * @param array $order
     * @return \Illuminate\Support\Collection
     */
    public static function getColumnListCommon($where = [] , $field='*' , $page=1 , $limit=10 , $order=[]) {
        $query = self::where($where)->offset(self::getOffsetByPage($page, $limit))->limit($limit);
        if($order) {
            $query = $query->orderBy(...$order);
        }
        return $query->pluck($field);
    }

    /**
     * 获取记录数
     *
     * @param array $where
     * @return int
     */
    public static function getCountCommon($where=[]) {
        $query = self::where($where);
        return $query->count();
    }

    /**
     * 删除
     *
     * @param mixed $where
     * @return int
     */
    public static function delCommon($where) {
        if(!$where) {
            return false;
        }
        return self::where($where)->delete();
    }

    /**
     * 删除,按主键
     * @param $pk
     * @return bool
     */
    public static function delByPkCommon($pk) {
        return self::destroy($pk);
    }

    /**
     * 获取主键
     *
     * @return string
     */
    public static function getPk() {
        return (new self)->primaryKey;
    }

    /**
     * 修改
     *
     * @param mixed $data
     * @param array $where
     * @param [int] $limit
     * @return int
     */
    public static function updateCommon($data, $where=[], $limit=null) {
        if(!$where) {
            $pk = self::getPk();
            $where = [$pk => $data[$pk]];
        }
        $query = self::where($where);
        if(!is_null($limit)) {
            $query->limit($limit);
        }
        return $query->update($data);
    }

    /**
     * 先查询后修改,便于走修改器
     *
     * @param [type] $data
     * @param [type] $pk
     * @return bool|int
     */
    public static function updateModelCommon($data, $pk) {
        $info = self::getLineByPkCommon($pk);
        if(!$info) {
            return false;
        }

        foreach($data as $k=>$v) {
            $info->$k = $v;
        }
        
        return $info->save();
    }

    /**
     * 自增
     *
     * @param [type] $where
     * @param [type] $field
     * @param integer $step
     * @param array $data
     * @return int
     * @throws Nette\InvalidArgumentException
     */
    public static function incCommon($where , $field , $step=1, $data=[]) {
        return self::where($where)->increment($field, $step, $data);
    }

    
    /**
     * 自减
     *
     * @param [type] $where
     * @param [type] $field
     * @param integer $step
     * @return int
     * @throws \Nette\InvalidArgumentException
     */
    public static function decCommon($where , $field , $step=1) {
        return self::where($where)->where($field , '>=' , $step)->decrement($field , $step);
    }

    /**
     * 添加
     *
     * @param [type] $data
     * @return int
     */
    public static function addCommon($data) {
        return self::insertGetId($data);
    }

    /**
     * 批量添加
     *
     * @param [type] $data
     * @return bool
     */
    public static function addBatchCommon($data) {
        return self::isnert($data);
    }

    /**
     * 整理list和count字段
     * @param $list
     * @param $count
     * @return ListWithCountStruct
     */
    public static function listWithCountCommon($list, $count) {
        return ListWithCountStruct::create($list, $count);
    }
}